package com.zhuhjay.common.web.annotation;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.zhuhjay.common.web.support.jackson.JsonDesensitizationSerializer;
import com.zhuhjay.common.web.support.jackson.JsonDesensitizationSupport;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * Json脱敏注解
 * @author ZhuHJay
 * @date 2023/2/25 13:26
 */
@Target({FIELD})
@Retention(RUNTIME)
@Documented
@JacksonAnnotationsInside
@JsonSerialize(using = JsonDesensitizationSerializer.class)
public @interface JsonDesensitization {
    /** 脱敏策略 **/
    Strategy strategy() default Strategy.TOTAL;

    /** 脱敏长度, 在 Strategy.RIGHT 和 Strategy.LEFT 策略下使用 **/
    int length() default 0;

    /** 脱敏字段替换字符 **/
    String replaceStr() default "*";

    /** 脱敏策略枚举 **/
    enum Strategy implements JsonDesensitizationSupport {
        /** 全部 **/
        TOTAL {
            @Override
            public String desensitization(String source, int length, String replaceStr) {
                return StrUtil.repeat(replaceStr, 6);
            }
        },
        /** 从左边开始 **/
        LEFT {
            @Override
            public String desensitization(String source, int length, String replaceStr) {
                if (StrUtil.isBlank(source)) {
                    return source;
                }
                if (source.length() <= length) {
                    return StrUtil.repeat(replaceStr, 6);
                }
                return replace(source, "^([\\s\\S]{" + length + "})", replaceStr, length);
            }
        },
        /** 从右边开始 **/
        RIGHT {
            @Override
            public String desensitization(String source, int length, String replaceStr) {
                if (StrUtil.isBlank(source)) {
                    return source;
                }
                if (source.length() <= length) {
                    return StrUtil.repeat(replaceStr, 6);
                }
                return replace(source, "[\\s\\S]{" + length + "}$", replaceStr, length);
            }
        },
        /** 手机号脱敏 **/
        TELEPHONE {
            @Override
            public String desensitization(String source, int length, String replaceStr) {
                return replace(source, "[\\d]{4}(?=[\\d]{4}$)", replaceStr, 4);
            }
        },
        /** 邮箱脱敏 **/
        EMAIL {
            @Override
            public String desensitization(String source, int length, String replaceStr) {
                return replace(source, "[\\s\\S]{6}(?=@)", replaceStr, 6);
            }
        };
    }
}
